﻿Imports System.Runtime.InteropServices
Imports System.ComponentModel
Imports System.IO
Imports System.Threading
Imports Microsoft.Win32

Public Class Form1

	Dim sProgress As String
	Dim sKombinaceKlaves As String
	Dim Def As New LoadSave.Definice
	Dim Title As String = "Remap concurrent keyboards"
	Private ResetEvent As New AutoResetEvent(False)	' kvuli pockani na BackgroundWorker.CancelAsync(), protoze to chvili trva nez nastavi promennou, ktera se pak cte a jeji obsah neodpovida

	Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
		Try
			' testovne vytvor context, jestli je vse v poradku s Interception.dll nebo driverem.
			Dim context As IntPtr = InterceptionWrapper.interception_create_context
			InterceptionWrapper.interception_destroy_context(context)
		Catch ex As Exception
			MsgBox(ex.Message & vbCrLf & "Program exits.")
			Environment.Exit(0)
		End Try

		'nastaveni DataGridView
		For Each x As DataGridViewColumn In dgvInput.Columns
			x.SortMode = DataGridViewColumnSortMode.NotSortable
		Next
		'Dim c As DataGridViewButtonColumn = CType(DGV.Columns("cKeyCombination"), DataGridViewButtonColumn)
		'c.FlatStyle = FlatStyle.Popup
		'c.DefaultCellStyle.ForeColor = Color.Yellow
		'c.DefaultCellStyle.BackColor = Color.Yellow

		InicializujSlovniky()

		LoadSave.NactiNastaveni()

		If AppSettings.AutoStart AndAlso Environment.GetCommandLineArgs.Contains("-StartFromRegistry") Then
			If LoadKeyboardRemap(AppSettings.PathToLastKeyboardSettings) Then
				RunKeyboardSettingsToolStripMenuItem.Enabled = False
				StopToolStripMenuItem.Enabled = True
				RunTheseKeyboardSettingsOnWindowsStartToolStripMenuItem.Checked = True
				Me.Text = Title & " - " & Path.GetFileName(LoadSave.Filename)
				btnStart_Click(sender, e)
			End If
		Else
			RunKeyboardSettingsToolStripMenuItem.Enabled = False
			StopToolStripMenuItem.Enabled = False
			Me.Text = Title & " - *not named"
			RunTheseKeyboardSettingsOnWindowsStartToolStripMenuItem.Checked = False
		End If

		grpKeyboards.Enabled = False
		grpKeyboardProfiles.Enabled = False
		grpInput.Enabled = False
		grpOutput.Enabled = False
		LoggingToolStripMenuItem.Checked = Interception.Logging
		NastavSirkuFormulare(Interception.Logging)


	End Sub



	Private Sub KeyTest3_v2(BW As BackgroundWorker)
		Dim hDll As IntPtr = LoadLibrary("interception.dll")
		Dim pointer_interception_is_keyboard As IntPtr = GetProcAddress(hDll, "interception_is_keyboard")
		Dim pointer_interception_is_mouse As IntPtr = GetProcAddress(hDll, "interception_is_mouse")

		Dim context As IntPtr
		Dim device As System.Int32


		' vytvor context
		context = InterceptionWrapper.interception_create_context
		' nastav filtry
		Dim MyFilter As System.UInt16 = InterceptionFilterKeyState.INTERCEPTION_FILTER_KEY_DOWN Or InterceptionFilterKeyState.INTERCEPTION_FILTER_KEY_E0 Or InterceptionFilterKeyState.INTERCEPTION_FILTER_KEY_UP
		InterceptionWrapper.interception_set_filter(context, pointer_interception_is_keyboard, MyFilter)

		'''''''' alokovani UNmanaged promennych v pameti a vytvoreni pointeru na ne
		' vseobsazny STROKE, je dan velikosti mouse stroke, protoze je vetsi nez key stroke
		Dim AllStroke As InterceptionMouseStroke
		Dim pAllStroke As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(AllStroke))
		Marshal.StructureToPtr(AllStroke, pAllStroke, False)
		' mouse stroke
		Dim MouseStroke As InterceptionMouseStroke
		Dim pMouseStroke As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(MouseStroke))
		Marshal.StructureToPtr(MouseStroke, pMouseStroke, False)
		' key stroke
		Dim KeyStrokeProPamet, OrigKeyStroke As InterceptionKeyStroke
		Dim pKeyStroke As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(KeyStrokeProPamet))
		Marshal.StructureToPtr(KeyStrokeProPamet, pKeyStroke, False)

		Const HardwareIDbufferSize = 2000
		Dim pHardwareID As IntPtr = Marshal.AllocHGlobal(HardwareIDbufferSize)

		' inicializace tridy pro kazdou klavesnici
		Dim dictHwIdKeyboard As New Dictionary(Of String, Interception.InterceptedKeyboard)
		For Each k In Def.Keyboards
			If Not k.Enabled Then Continue For
			Dim hlpIntKeyboard As New Interception.InterceptedKeyboard

			For Each p In k.Profiles
				If Not p.Enabled Then Continue For

				For i = 0 To p.Inputs.Count - 1
					If Not p.Inputs(i).Enabled Then Continue For
					If p.Inputs(i).Strokes.Count = 0 Then Continue For
					' pokud je vyzadovano, uprav poradi a modifier keys a podle teto upravene vstupni sekvence dohledej sekvenci vystupni
					Dim hlpStrokes As List(Of Interception.InterceptionKeyStroke) = p.Inputs(i).Strokes.ToList
					hlpStrokes = UpravSeznamStrokuu(hlpStrokes)
					hlpIntKeyboard.Inputs.Add(hlpStrokes) ' ulozeni

					Dim hlp As New List(Of List(Of Interception.InterceptionKeyStroke))
					For o = 0 To p.Inputs(i).Outputs.Count - 1
						If Not p.Inputs(i).Outputs(o).Enabled Then Continue For
						If p.Inputs(i).Outputs(o).Strokes.Count = 0 Then Continue For
						' pokud je vyzadovano, uprav poradi a modifier keys a podle teto upravene vstupni sekvence dohledej sekvenci vystupni
						Dim hlpStrokes2 As List(Of Interception.InterceptionKeyStroke) = p.Inputs(i).Outputs(o).Strokes.ToList
						hlpStrokes2 = UpravSeznamStrokuu(hlpStrokes2)
						hlp.Add(hlpStrokes2)
					Next
					hlpIntKeyboard.Outputs.Add(hlp)
				Next
			Next

			dictHwIdKeyboard.Add(k.HwID, hlpIntKeyboard)
		Next

		Dim IntKeyb As New Interception.InterceptedKeyboard
		Dim lstUpravenychStroke As List(Of Interception.InterceptionKeyStroke)

		Try

			Do
				If BW.CancellationPending Then
					Exit Do
				End If

				' zarizeni na kterem byla akce
				device = InterceptionWrapper.interception_wait_with_timeout(context, 1)

				' zarizeni je klavesnice
				If InterceptionWrapper.interception_is_keyboard(device) Then

					' co se zmacklo
					Dim receive As System.Int32 = InterceptionWrapper.interception_receive(context, device, pAllStroke, 1)
					If receive = 0 Then Continue Do
					OrigKeyStroke = CType(Marshal.PtrToStructure(pAllStroke, GetType(InterceptionKeyStroke)), InterceptionKeyStroke)

					' dej HardwareID a pro neho seznam vstupu a vystupu
					Dim HardwareIDLength As System.Int32 = InterceptionWrapper.interception_get_hardware_id(context, device, pHardwareID, HardwareIDbufferSize)
					Dim sDevice As String = "none"
					If HardwareIDLength > 0 And HardwareIDLength < HardwareIDbufferSize Then
						sDevice = Marshal.PtrToStringAuto(pHardwareID)
					End If

					' dej uzivateli vedet co se zmacklo
					Dim sOrigState As String = "none"
					If (OrigKeyStroke.state And InterceptionKeyState.INTERCEPTION_KEY_UP) = InterceptionKeyState.INTERCEPTION_KEY_UP Then
						sOrigState = "UP"
					ElseIf (OrigKeyStroke.state And InterceptionKeyState.INTERCEPTION_KEY_DOWN) = InterceptionKeyState.INTERCEPTION_KEY_DOWN Then
						sOrigState = "DOWN"
					End If
					LogujPraci(sDevice, OrigKeyStroke, sOrigState, BW)


					' protoze muze byt zmacknuto ve stejnou chvili vice klavesnic, je zapotrebi nacitat a ukladat nektere promenne pro kazdou klavesnici
					If Not dictHwIdKeyboard.TryGetValue(sDevice, IntKeyb) Then
						Marshal.StructureToPtr(OrigKeyStroke, pKeyStroke, False)
						Dim SendResult As System.Int32 = InterceptionWrapper.interception_send(context, device, pKeyStroke, 1)

						LogujPraci("send", OrigKeyStroke, sOrigState, BW)
						Continue Do	' pokud neni klavesnice v hlidanych, tak cekej na dalsi vstup
					End If

					' zjisti code
					Dim KeyStroke As New InterceptionKeyStroke With {.code = OrigKeyStroke.code}

					' zjisti E0 nebo E1
					Dim sState As String = ""
					If (OrigKeyStroke.state And InterceptionKeyState.INTERCEPTION_KEY_E0) = InterceptionKeyState.INTERCEPTION_KEY_E0 Then
						sState = sState & "E0"
						KeyStroke.state = KeyStroke.state Or InterceptionKeyState.INTERCEPTION_KEY_E0
					ElseIf (OrigKeyStroke.state And InterceptionKeyState.INTERCEPTION_KEY_E1) = InterceptionKeyState.INTERCEPTION_KEY_E1 Then
						sState = sState & "E1"
						KeyStroke.state = KeyStroke.state Or InterceptionKeyState.INTERCEPTION_KEY_E1
					End If


					If (OrigKeyStroke.state And InterceptionKeyState.INTERCEPTION_KEY_UP) = InterceptionKeyState.INTERCEPTION_KEY_UP Then
						sState = sState & "UP+"

						' odstran z REAL
						Dim ind As Integer = IntKeyb.RealPressedKeys.FindIndex(Function(x) x = KeyStroke)
						If ind <> -1 Then	' byl nalezen
							IntKeyb.RealPressedKeys.RemoveAt(ind)
						End If

						' odstran ze SYSTEM
						ind = IntKeyb.SystemPressedKeys.FindIndex(Function(x) x = KeyStroke)
						If ind <> -1 Then	' byl nalezen
							IntKeyb.SystemPressedKeys.RemoveAt(ind)

							Dim hlpKeyStroke As Interception.InterceptionKeyStroke = VytvorKeyStroke(KeyStroke.code, KeyStroke.state Or InterceptionKeyState.INTERCEPTION_KEY_UP)
							Marshal.StructureToPtr(hlpKeyStroke, pKeyStroke, False)
							Dim SendResult As System.Int32 = InterceptionWrapper.interception_send(context, device, pKeyStroke, 1)

							LogujPraci("send", hlpKeyStroke, "UP", BW)

						Else ' nebyl nalezen

						End If
					ElseIf (OrigKeyStroke.state And InterceptionKeyState.INTERCEPTION_KEY_DOWN) = InterceptionKeyState.INTERCEPTION_KEY_DOWN Then
						sState = sState & "DOWN+"

						' ========================== pridej KEY do REAL
						Dim ind As Integer = IntKeyb.RealPressedKeys.FindIndex(Function(x) x = KeyStroke)
						If ind = -1 Then
							IntKeyb.RealPressedKeys.Add(KeyStroke)
						End If

						' pokud je vyzadovano, uprav poradi a modifier keys a podle teto upravene vstupni sekvence dohledej sekvenci vystupni
						lstUpravenychStroke = IntKeyb.RealPressedKeys.ToList
						lstUpravenychStroke = UpravSeznamStrokuu(lstUpravenychStroke)

						' dohledej vystupni sekvenci
						Dim lstOutputs As List(Of List(Of Interception.InterceptionKeyStroke)) = DejOutput(IntKeyb, lstUpravenychStroke)

						Dim hlpKeyStroke As Interception.InterceptionKeyStroke
						If (lstOutputs.Count = 0) Then ' ==== REAL NEobsahuje shortcut
							' zjisti doplnek REAL do SYSTEM
							Dim Doplnek As List(Of Interception.InterceptionKeyStroke) = DejDoplnekREALdoSYSTEM(IntKeyb.RealPressedKeys, IntKeyb.SystemPressedKeys)

							If Doplnek.Count = 0 Then ' neni doplnek, tak posli posledni vlozeny keystroke
								Dim LastKS As Interception.InterceptionKeyStroke = IntKeyb.SystemPressedKeys.Last
								hlpKeyStroke = VytvorKeyStroke(LastKS.code, LastKS.state Or InterceptionKeyState.INTERCEPTION_KEY_DOWN)
								Marshal.StructureToPtr(hlpKeyStroke, pKeyStroke, False)
								Dim SendResult As System.Int32 = InterceptionWrapper.interception_send(context, device, pKeyStroke, 1)

								LogujPraci("send", hlpKeyStroke, "DOWN", BW)
							Else ' je doplnek, tak ho posli do windowsu
								For Each ks In Doplnek
									hlpKeyStroke = VytvorKeyStroke(ks.code, ks.state Or InterceptionKeyState.INTERCEPTION_KEY_DOWN)
									Marshal.StructureToPtr(hlpKeyStroke, pKeyStroke, False)
									Dim SendResult As System.Int32 = InterceptionWrapper.interception_send(context, device, pKeyStroke, 1)

									LogujPraci("send", hlpKeyStroke, "DOWN", BW)
								Next
								IntKeyb.SystemPressedKeys = IntKeyb.RealPressedKeys.ToList
							End If

						Else ' ==== REAL obsahuje nektery z uzivatelem definovanych shortcutuu

							LogujPraci_v2("UPovani SYSTEM listu", BW)

							' UPuj SYSTEM 
							For n = 0 To IntKeyb.SystemPressedKeys.Count - 1
								Dim ks As InterceptionKeyStroke = IntKeyb.SystemPressedKeys(n)
								hlpKeyStroke = VytvorKeyStroke(ks.code, ks.state Or InterceptionKeyState.INTERCEPTION_KEY_UP)
								Marshal.StructureToPtr(hlpKeyStroke, pKeyStroke, False)
								Dim SendResult As System.Int32 = InterceptionWrapper.interception_send(context, device, pKeyStroke, 1)

								LogujPraci("send", hlpKeyStroke, "UP", BW)
							Next
							IntKeyb.SystemPressedKeys.Clear()

							' simuluj zmacknuti a uvolneni klaves vystupni kombinace
							For Each o In lstOutputs
								' simuluj DOWN pro celou OUTPUT sekvenci
								For Each ks In o
									hlpKeyStroke = VytvorKeyStroke(ks.code, ks.state Or InterceptionKeyState.INTERCEPTION_KEY_DOWN)
									Marshal.StructureToPtr(hlpKeyStroke, pKeyStroke, False)
									Dim SendResult As System.Int32 = InterceptionWrapper.interception_send(context, device, pKeyStroke, 1)

									LogujPraci("send", hlpKeyStroke, "DOWN", BW)
								Next
								' simuluj UP pro celou OUTPUT sekvenci
								For Each ks In o
									hlpKeyStroke = VytvorKeyStroke(ks.code, ks.state Or InterceptionKeyState.INTERCEPTION_KEY_UP)
									Marshal.StructureToPtr(hlpKeyStroke, pKeyStroke, False)
									Dim SendResult As System.Int32 = InterceptionWrapper.interception_send(context, device, pKeyStroke, 1)

									LogujPraci("send", hlpKeyStroke, "UP", BW)
								Next
							Next

						End If

					End If

					' ulozeni promennych pro danou klavesnici
					dictHwIdKeyboard(sDevice) = IntKeyb
				End If
			Loop

		Catch ex As Exception
			MsgBox(ex.Message & vbCrLf & "Program stops remapping.")
		End Try

		InterceptionWrapper.interception_destroy_context(context)

		' uvolneni unmanaged promennych
		Marshal.FreeHGlobal(pAllStroke)
		Marshal.FreeHGlobal(pMouseStroke)
		Marshal.FreeHGlobal(pKeyStroke)

		FreeLibrary(hDll)

		ResetEvent.Set()
	End Sub

	Public Sub LogujPraci(sAkce As String, ks As Interception.InterceptionKeyStroke, state As String, BW As BackgroundWorker)
		If Interception.Logging Then
			Const SleepTime = 10

			sProgress = sAkce & " : " & DejKey(ks) & " : " & state
			BW.ReportProgress(1)
			Thread.Sleep(SleepTime)
		End If
	End Sub

	Public Sub LogujPraci_v2(sAkce As String, BW As BackgroundWorker)
		If Interception.Logging Then
			Const SleepTime = 10

			sProgress = sAkce
			BW.ReportProgress(1)
			Thread.Sleep(SleepTime)
		End If
	End Sub

	Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
		Dim BW As BackgroundWorker = CType(sender, BackgroundWorker)
		KeyTest3_v2(BW)
	End Sub

	Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
		lstProgress.Items.Add(sProgress)
		lstProgress.TopIndex = lstProgress.Items.Count - 1
	End Sub


	Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
		'MsgBox("Ukonceno.")
		btnStart.Enabled = True
		btnStop.Enabled = False
	End Sub

	Private Sub btnStart_Click(sender As Object, e As EventArgs) Handles btnStart.Click, RunKeyboardSettingsToolStripMenuItem.Click

		If Not BackgroundWorker1.IsBusy Then
			BackgroundWorker1.RunWorkerAsync()
			btnStart.Enabled = False
			RunKeyboardSettingsToolStripMenuItem.Enabled = False
			btnStop.Enabled = True
			StopToolStripMenuItem.Enabled = True

			NewToolStripMenuItem.Enabled = False
			EditToolStripMenuItem.Enabled = False
			LoadToolStripMenuItem.Enabled = False
			SaveToolStripMenuItem.Enabled = False
			SaveAsToolStripMenuItem.Enabled = False
		End If
	End Sub

	Private Sub btnStop_Click(sender As Object, e As EventArgs) Handles btnStop.Click, StopToolStripMenuItem.Click
		If BackgroundWorker1.IsBusy Then
			BackgroundWorker1.CancelAsync()
			ResetEvent.WaitOne()
			btnStart.Enabled = True
			RunKeyboardSettingsToolStripMenuItem.Enabled = True
			btnStop.Enabled = False
			StopToolStripMenuItem.Enabled = False

			NewToolStripMenuItem.Enabled = True
			EditToolStripMenuItem.Enabled = True
			LoadToolStripMenuItem.Enabled = True
			SaveToolStripMenuItem.Enabled = True
			SaveAsToolStripMenuItem.Enabled = True
		End If
	End Sub

	Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
		lstProgress.Items.Clear()
	End Sub


	''' <summary>
	''' KEYBOARD datagridview
	''' </summary>
	Private Sub btnKeyboardAdd_Click(sender As Object, e As EventArgs) Handles btnKeyboardAdd.Click
		RemoveHandler dgvKeyboard.RowEnter, AddressOf dgvKeyboard_RowEnter ' dgvKeyboard.Rows.Add() vyvola OnRowEnter a to se nehodi
		dgvKeyboard.Rows.Add()
		dgvKeyboard.Rows(dgvKeyboard.Rows.Count - 1).Cells("cKeyboardHwID").Value = "- click to set -"
		dgvKeyboard.Rows(dgvKeyboard.Rows.Count - 1).Cells("cKeyboardEnabled").Value = True
		dgvKeyboard.CurrentCell = dgvKeyboard(0, dgvKeyboard.Rows.Count - 1)
		dgvKeyboard.BeginEdit(True)
		Def.Keyboards.Add(New LoadSave.Keyboard With {.Name = "", .HwID = "", .Enabled = True})
		AddHandler dgvKeyboard.RowEnter, AddressOf dgvKeyboard_RowEnter
	End Sub

	Private Sub btnKeyboardRemove_Click(sender As Object, e As EventArgs) Handles btnKeyboardRemove.Click
		If (dgvKeyboard.CurrentCell IsNot Nothing) AndAlso (dgvKeyboard.CurrentCell.RowIndex >= 0) Then
			Dim KeyboardIndex As Integer = dgvKeyboard.CurrentCell.RowIndex
			' odstran z definice
			Def.Keyboards.RemoveAt(KeyboardIndex)
			' odstran z DGV
			RemoveHandler dgvKeyboard.RowEnter, AddressOf dgvKeyboard_RowEnter ' dgvKeyboard.Rows.Add() vyvola OnRowEnter a to se nehodi
			dgvKeyboard.Rows.RemoveAt(KeyboardIndex)
			AddHandler dgvKeyboard.RowEnter, AddressOf dgvKeyboard_RowEnter
		End If
	End Sub

	Private Sub dgvKeyboard_CellEndEdit(sender As Object, e As DataGridViewCellEventArgs) Handles dgvKeyboard.CellEndEdit
		AktualizujKeyboardVDefinici()
	End Sub

	Private Sub dgvKeyboard_RowEnter(sender As Object, e As DataGridViewCellEventArgs) Handles dgvKeyboard.RowEnter
		Dim KeyboardIndex As Integer = e.RowIndex
		PridejPolozkyDoDGVkeyboardProfile(KeyboardIndex)
	End Sub

	Private Sub dgvKeyboard_RowsAdded(sender As Object, e As DataGridViewRowsAddedEventArgs) Handles dgvKeyboard.RowsAdded
		Dim KeyboardIndex As Integer = e.RowIndex
		PridejPolozkyDoDGVkeyboardProfile(KeyboardIndex)
	End Sub

	Private Sub dgvKeyboard_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles dgvKeyboard.CellContentClick
		Dim hlpDGV As DataGridView = CType(sender, DataGridView)
		If TypeOf hlpDGV.Columns(e.ColumnIndex) Is DataGridViewButtonColumn Then
			If 0 <= e.RowIndex Then
				' pust formular se zaznamem stisknutych klaves nebo vyberem klaves z ComboBoxuu
				Form3.ShowDialog()
				If Form3.HwID IsNot Nothing Then
					dgvKeyboard.Item(e.ColumnIndex, e.RowIndex).Value = Form3.HwID
					AktualizujKeyboardVDefinici()
					'dgvKeyboard.EndEdit()
				End If
			End If
		End If

		If TypeOf hlpDGV.Columns(e.ColumnIndex) Is DataGridViewCheckBoxColumn Then
			dgvKeyboard.EndEdit()
		End If

	End Sub

	Public Sub AktualizujKeyboardVDefinici()
		Dim KeyboardIndex As Integer = dgvKeyboard.CurrentCell.RowIndex
		Def.Keyboards(KeyboardIndex).Name = dgvKeyboard.Rows(KeyboardIndex).Cells("cKeyboardName").Value
		Def.Keyboards(KeyboardIndex).HwID = dgvKeyboard.Rows(KeyboardIndex).Cells("cKeyboardHwId").Value
		Def.Keyboards(KeyboardIndex).Enabled = dgvKeyboard.Rows(KeyboardIndex).Cells("cKeyboardEnabled").Value
	End Sub

	''' <summary>
	''' PROFILE datagridview
	''' </summary>
	Private Sub btnProfileAdd_Click(sender As Object, e As EventArgs) Handles btnProfileAdd.Click
		RemoveHandler dgvKeyboardProfile.RowEnter, AddressOf dgvKeyboardProfile_RowEnter	' dgvKeyboardProfile.Rows.Add() vyvola OnRowEnter a to se nehodi
		dgvKeyboardProfile.Rows.Add()
		dgvKeyboardProfile.Rows(dgvKeyboardProfile.Rows.Count - 1).Cells("cProfileEnabled").Value = True
		dgvKeyboardProfile.CurrentCell = dgvKeyboardProfile(0, dgvKeyboardProfile.Rows.Count - 1)
		dgvKeyboardProfile.BeginEdit(True)
		Dim KeyboardIndex As Integer = dgvKeyboard.CurrentCell.RowIndex
		Def.Keyboards(KeyboardIndex).Profiles.Add(New LoadSave.Profile With {.Name = "", .Enabled = True})
		AddHandler dgvKeyboardProfile.RowEnter, AddressOf dgvKeyboardProfile_RowEnter
	End Sub

	Private Sub btnProfileRemove_Click(sender As Object, e As EventArgs) Handles btnProfileRemove.Click
		If (dgvKeyboardProfile.CurrentCell IsNot Nothing) AndAlso (dgvKeyboardProfile.CurrentCell.RowIndex >= 0) Then
			Dim KeyboardIndex As Integer = dgvKeyboard.CurrentCell.RowIndex
			Dim ProfileIndex As Integer = dgvKeyboardProfile.CurrentCell.RowIndex
			' odstran z definice
			Def.Keyboards(KeyboardIndex).Profiles.RemoveAt(ProfileIndex)
			' odstran z DGV
			RemoveHandler dgvKeyboardProfile.RowEnter, AddressOf dgvKeyboardProfile_RowEnter	' dgvKeyboardProfile.Rows.Add() vyvola OnRowEnter a to se nehodi
			dgvKeyboardProfile.Rows.RemoveAt(ProfileIndex)
			AddHandler dgvKeyboardProfile.RowEnter, AddressOf dgvKeyboardProfile_RowEnter
		End If
	End Sub

	Private Sub dgvKeyboardProfile_CellEndEdit(sender As Object, e As DataGridViewCellEventArgs) Handles dgvKeyboardProfile.CellEndEdit
		AktualizujProfileVDefinici()
	End Sub

	Private Sub dgvKeyboardProfile_RowEnter(sender As Object, e As DataGridViewCellEventArgs) Handles dgvKeyboardProfile.RowEnter
		Dim KeyboardIndex As Integer = dgvKeyboard.CurrentCell.RowIndex
		Dim ProfileIndex As Integer = e.RowIndex
		PridejPolozkyDoDGVinput(KeyboardIndex, ProfileIndex)
	End Sub

	Private Sub dgvKeyboardProfile_RowsAdded(sender As Object, e As DataGridViewRowsAddedEventArgs) Handles dgvKeyboardProfile.RowsAdded
		Dim KeyboardIndex As Integer = dgvKeyboard.CurrentCell.RowIndex
		Dim ProfileIndex As Integer = e.RowIndex
		PridejPolozkyDoDGVinput(KeyboardIndex, ProfileIndex)
	End Sub

	Private Sub dgvKeyboardProfile_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles dgvKeyboardProfile.CellContentClick
		Dim hlpDGV As DataGridView = CType(sender, DataGridView)
		If TypeOf hlpDGV.Columns(e.ColumnIndex) Is DataGridViewCheckBoxColumn Then
			dgvKeyboardProfile.EndEdit()
		End If
	End Sub

	Public Sub AktualizujProfileVDefinici()
		Dim KeyboardIndex As Integer = dgvKeyboard.CurrentCell.RowIndex
		Dim ProfileIndex As Integer = dgvKeyboardProfile.CurrentCell.RowIndex
		Def.Keyboards(KeyboardIndex).Profiles(ProfileIndex).Name = dgvKeyboardProfile.Rows(ProfileIndex).Cells("cProfileName").Value
		Def.Keyboards(KeyboardIndex).Profiles(ProfileIndex).Enabled = dgvKeyboardProfile.Rows(ProfileIndex).Cells("cProfileEnabled").Value
	End Sub

	''' <summary>
	''' INPUT datagridview
	''' </summary>
	Private Sub btnInputAdd_Click(sender As Object, e As EventArgs) Handles btnInputAdd.Click
		RemoveHandler dgvInput.RowEnter, AddressOf dgvInput_RowEnter
		dgvInput.Rows.Add()
		dgvInput.Rows(dgvInput.Rows.Count - 1).Cells("cInputKeyCombination").Value = "- click to set -"
		dgvInput.Rows(dgvInput.Rows.Count - 1).Cells("cInputEnabled").Value = True
		dgvInput.CurrentCell = dgvInput(0, dgvInput.Rows.Count - 1)
		dgvInput.BeginEdit(True)
		' pridej novej Input do definice
		Dim KeyboardIndex As Integer = dgvKeyboard.CurrentCell.RowIndex
		Dim ProfileIndex As Integer = dgvKeyboardProfile.CurrentCell.RowIndex
		Def.Keyboards(KeyboardIndex).Profiles(ProfileIndex).Inputs.Add(New LoadSave.Input With {.Name = "", .Enabled = True})
		AddHandler dgvInput.RowEnter, AddressOf dgvInput_RowEnter
	End Sub

	Private Sub btnInputRemove_Click(sender As Object, e As EventArgs) Handles btnInputRemove.Click
		If (dgvInput.CurrentCell IsNot Nothing) AndAlso (dgvInput.CurrentCell.RowIndex >= 0) Then
			Dim KeyboardIndex As Integer = dgvKeyboard.CurrentCell.RowIndex
			Dim ProfileIndex As Integer = dgvKeyboardProfile.CurrentCell.RowIndex
			Dim InputIndex As Integer = dgvInput.CurrentCell.RowIndex
			' odstran z definice
			Def.Keyboards(KeyboardIndex).Profiles(ProfileIndex).Inputs.RemoveAt(InputIndex)
			' odstran z DGV
			RemoveHandler dgvInput.RowEnter, AddressOf dgvInput_RowEnter
			dgvInput.Rows.RemoveAt(InputIndex)
			AddHandler dgvInput.RowEnter, AddressOf dgvInput_RowEnter
		End If
	End Sub

	Private Sub dgvInput_CellEndEdit(sender As Object, e As DataGridViewCellEventArgs) Handles dgvInput.CellEndEdit
		AktualizujInputVDefinici()
	End Sub

	Private Sub dgvInput_RowEnter(sender As Object, e As DataGridViewCellEventArgs) Handles dgvInput.RowEnter
		Dim KeyboardIndex As Integer = dgvKeyboard.CurrentCell.RowIndex
		Dim ProfileIndex As Integer = dgvKeyboardProfile.CurrentCell.RowIndex
		Dim InputIndex As Integer = e.RowIndex
		PridejPolozkyDoDGVoutput(KeyboardIndex, ProfileIndex, InputIndex)
	End Sub

	Private Sub dgvInput_RowsAdded(sender As Object, e As DataGridViewRowsAddedEventArgs) Handles dgvInput.RowsAdded
		Dim KeyboardIndex As Integer = dgvKeyboard.CurrentCell.RowIndex
		Dim ProfileIndex As Integer = dgvKeyboardProfile.CurrentCell.RowIndex
		Dim InputIndex As Integer = e.RowIndex
		PridejPolozkyDoDGVoutput(KeyboardIndex, ProfileIndex, InputIndex)
	End Sub

	Private Sub dgvInput_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles dgvInput.CellContentClick
		If TypeOf dgvInput.Columns(e.ColumnIndex) Is DataGridViewButtonColumn Then
			If 0 <= e.RowIndex Then
				' pust formular se zaznamem stisknutych klaves nebo vyberem klaves z ComboBoxuu
				Form2.ShowDialog()
				Dim lstVybranychStroke As List(Of Interception.InterceptionKeyStroke) = Form2.lstVybranychStroke
				If lstVybranychStroke IsNot Nothing Then
					' pridej do definice
					Dim KeyboardIndex As Integer = dgvKeyboard.CurrentCell.RowIndex
					Dim ProfileIndex As Integer = dgvKeyboardProfile.CurrentCell.RowIndex
					Dim InputIndex As Integer = dgvInput.CurrentCell.RowIndex
					Def.Keyboards(KeyboardIndex).Profiles(ProfileIndex).Inputs(InputIndex).Strokes = lstVybranychStroke.ToList
					' zobraz kombinaci v dgvInput
					dgvInput.Item(e.ColumnIndex, e.RowIndex).Value = DejRetezecZeSeznamuStroku(lstVybranychStroke)
				End If
			End If
		End If
		If TypeOf dgvInput.Columns(e.ColumnIndex) Is DataGridViewCheckBoxColumn Then
			dgvInput.EndEdit()
		End If
	End Sub

	Public Sub AktualizujInputVDefinici()
		Dim KeyboardIndex As Integer = dgvKeyboard.CurrentCell.RowIndex
		Dim ProfileIndex As Integer = dgvKeyboardProfile.CurrentCell.RowIndex
		Dim InputIndex As Integer = dgvInput.CurrentCell.RowIndex
		Def.Keyboards(KeyboardIndex).Profiles(ProfileIndex).Inputs(InputIndex).Name = dgvInput.Rows(InputIndex).Cells("cInputName").Value
		Def.Keyboards(KeyboardIndex).Profiles(ProfileIndex).Inputs(InputIndex).Enabled = dgvInput.Rows(InputIndex).Cells("cInputEnabled").Value
	End Sub

	''' <summary>
	''' OUTPUT datagridview
	''' </summary>
	Private Sub btnOutputAdd_Click(sender As Object, e As EventArgs) Handles btnOutputAdd.Click
		RemoveHandler dgvOutput.RowEnter, AddressOf dgvOutput_RowEnter
		dgvOutput.Rows.Add()
		dgvOutput.Rows(dgvOutput.Rows.Count - 1).Cells("cOutputKeyCombination").Value = "- click to set -"
		dgvOutput.Rows(dgvOutput.Rows.Count - 1).Cells("cOutputEnabled").Value = True
		dgvOutput.CurrentCell = dgvOutput(0, dgvOutput.Rows.Count - 1)
		dgvOutput.BeginEdit(True)
		' pridej novej Output do definice
		Dim KeyboardIndex As Integer = dgvKeyboard.CurrentCell.RowIndex
		Dim ProfileIndex As Integer = dgvKeyboardProfile.CurrentCell.RowIndex
		Dim InputIndex As Integer = dgvInput.CurrentCell.RowIndex
		Def.Keyboards(KeyboardIndex).Profiles(ProfileIndex).Inputs(InputIndex).Outputs.Add(New LoadSave.Output With {.Enabled = True})
		AddHandler dgvOutput.RowEnter, AddressOf dgvOutput_RowEnter
	End Sub

	Private Sub btnOutputRemove_Click(sender As Object, e As EventArgs) Handles btnOutputRemove.Click
		If (dgvOutput.CurrentCell IsNot Nothing) AndAlso (dgvOutput.CurrentCell.RowIndex >= 0) Then
			Dim KeyboardIndex As Integer = dgvKeyboard.CurrentCell.RowIndex
			Dim ProfileIndex As Integer = dgvKeyboardProfile.CurrentCell.RowIndex
			Dim InputIndex As Integer = dgvInput.CurrentCell.RowIndex
			Dim OutputIndex As Integer = dgvOutput.CurrentCell.RowIndex
			' odstran z definice
			Def.Keyboards(KeyboardIndex).Profiles(ProfileIndex).Inputs(InputIndex).Outputs.RemoveAt(OutputIndex)
			' odstran z DGV
			RemoveHandler dgvOutput.RowEnter, AddressOf dgvOutput_RowEnter
			dgvOutput.Rows.RemoveAt(dgvOutput.CurrentCell.RowIndex)
			AddHandler dgvOutput.RowEnter, AddressOf dgvOutput_RowEnter
		End If
	End Sub

	Private Sub dgvOutput_CellEndEdit(sender As Object, e As DataGridViewCellEventArgs) Handles dgvOutput.CellEndEdit
		AktualizujOutputVDefinici()
	End Sub

	Private Sub dgvOutput_RowEnter(sender As Object, e As DataGridViewCellEventArgs) Handles dgvOutput.RowEnter
		' odsud se uz nic neaktualizuje
	End Sub

	Private Sub dgvOutput_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles dgvOutput.CellContentClick
		If TypeOf dgvOutput.Columns(e.ColumnIndex) Is DataGridViewButtonColumn Then
			If 0 <= e.RowIndex Then
				' pust formular se zaznamem stisknutych klaves nebo vyberem klaves z ComboBoxuu
				Form2.ShowDialog()
				Dim lstVybranychStroke As List(Of Interception.InterceptionKeyStroke) = Form2.lstVybranychStroke
				If lstVybranychStroke IsNot Nothing Then
					' pridej do definice
					Dim KeyboardIndex As Integer = dgvKeyboard.CurrentCell.RowIndex
					Dim ProfileIndex As Integer = dgvKeyboardProfile.CurrentCell.RowIndex
					Dim InputIndex As Integer = dgvInput.CurrentCell.RowIndex
					Dim OutputIndex As Integer = dgvOutput.CurrentCell.RowIndex
					Def.Keyboards(KeyboardIndex).Profiles(ProfileIndex).Inputs(InputIndex).Outputs(OutputIndex).Strokes = lstVybranychStroke.ToList
					' zobraz kombinaci v dgvOutput
					dgvOutput.Item(e.ColumnIndex, e.RowIndex).Value = DejRetezecZeSeznamuStroku(lstVybranychStroke)
				End If
			End If
		End If
		If TypeOf dgvOutput.Columns(e.ColumnIndex) Is DataGridViewCheckBoxColumn Then
			dgvOutput.EndEdit()
		End If
	End Sub

	Public Sub AktualizujOutputVDefinici()
		Dim KeyboardIndex As Integer = dgvKeyboard.CurrentCell.RowIndex
		Dim ProfileIndex As Integer = dgvKeyboardProfile.CurrentCell.RowIndex
		Dim InputIndex As Integer = dgvInput.CurrentCell.RowIndex
		Dim OutputIndex As Integer = dgvOutput.CurrentCell.RowIndex
		Def.Keyboards(KeyboardIndex).Profiles(ProfileIndex).Inputs(InputIndex).Outputs(OutputIndex).Enabled = dgvOutput.Rows(OutputIndex).Cells("cOutputEnabled").Value
	End Sub

	''' <summary>
	''' GRAPHICS section
	''' </summary>
	Private Sub ChangeDGVappearance(dgv As DataGridView, e As EventArgs) Handles dgvKeyboard.EnabledChanged, dgvKeyboardProfile.EnabledChanged, dgvInput.EnabledChanged, dgvOutput.EnabledChanged
		If Not dgv.Enabled Then
			dgv.DefaultCellStyle.BackColor = Color.LightGray
			dgv.ReadOnly = True
			dgv.BackgroundColor = Color.LightGray
		Else
			dgv.DefaultCellStyle.BackColor = SystemColors.Window
			dgv.ReadOnly = False
			dgv.BackgroundColor = Color.White
		End If
	End Sub


	Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles MyBase.Paint
		Dim g As Graphics

		g = e.Graphics

		Dim myPen As Pen = New Pen(Color.Green)
		myPen.Width = 5

		ZmenBarvuPera(myPen, grpKeyboards.Enabled Or grpKeyboardProfiles.Enabled Or grpInput.Enabled Or grpOutput.Enabled)
		g.FillRectangle(myPen.Brush, GetRect(grpKeyboards))
		g.DrawLine(myPen, GetXYofObjectSideCenter(KeyboardSettingsToolStripMenuItem, enumSide.Bottom), GetXYofObjectSideCenter(grpKeyboards, enumSide.Top))

		ZmenBarvuPera(myPen, grpKeyboardProfiles.Enabled Or grpInput.Enabled Or grpOutput.Enabled)
		g.FillRectangle(myPen.Brush, GetRect(grpKeyboardProfiles))
		g.DrawLine(myPen, GetXYofObjectSideCenter(grpKeyboards, enumSide.Right), GetXYofObjectSideCenter(grpKeyboardProfiles, enumSide.Left))

		ZmenBarvuPera(myPen, grpInput.Enabled Or grpOutput.Enabled)
		g.FillRectangle(myPen.Brush, GetRect(grpInput))
		g.DrawLine(myPen, GetXYofObjectSideCenter(grpKeyboardProfiles, enumSide.Bottom), GetXYofObjectSideCenter(grpInput, enumSide.Top))

		ZmenBarvuPera(myPen, grpOutput.Enabled)
		g.FillRectangle(myPen.Brush, GetRect(grpOutput))
		g.DrawLine(myPen, GetXYofObjectSideCenter(grpInput, enumSide.Right), GetXYofObjectSideCenter(grpOutput, enumSide.Left))

	End Sub

	Private Sub ZmenBarvuPera(ByRef myPen As Pen, b As Boolean)
		If b Then
			myPen.Color = Color.LimeGreen
		Else
			myPen.Color = Color.LightSlateGray
		End If
	End Sub

	Enum enumSide
		Top
		Left
		Bottom
		Right
	End Enum

	Private Function GetRect(con As Control) As Rectangle
		Dim r As Rectangle
		r.Y = con.Top - 5
		r.X = con.Left - 5
		r.Width = con.Width + 10
		r.Height = con.Height + 10
		Return r
	End Function

	Private Function GetXYofObjectSideCenter(con As Control, Side As enumSide) As Point
		If Side = enumSide.Top Then
			Return New Point With {.X = CInt(con.Left + con.Width / 2), .Y = con.Top}
		ElseIf Side = enumSide.Left Then
			Return New Point With {.X = con.Left, .Y = CInt(con.Top + con.Height / 2)}
		ElseIf Side = enumSide.Bottom Then
			Return New Point With {.X = CInt(con.Left + con.Width / 2), .Y = con.Top + con.Height}
		ElseIf Side = enumSide.Right Then
			Return New Point With {.X = con.Left + con.Width, .Y = CInt(con.Top + con.Height / 2)}
		End If
	End Function

	Private Function GetXYofObjectSideCenter(con As ToolStripMenuItem, Side As enumSide) As Point
		If Side = enumSide.Top Then
			Return New Point With {.X = CInt(con.Bounds.Left + con.Width / 2), .Y = con.Bounds.Top}
		ElseIf Side = enumSide.Left Then
			Return New Point With {.X = con.Bounds.Left, .Y = CInt(con.Bounds.Top + con.Bounds.Height / 2)}
		ElseIf Side = enumSide.Bottom Then
			Return New Point With {.X = CInt(con.Bounds.Left + con.Width / 2), .Y = con.Bounds.Top + con.Height}
		ElseIf Side = enumSide.Right Then
			Return New Point With {.X = con.Bounds.Left + con.Width, .Y = CInt(con.Bounds.Top + con.Bounds.Height / 2)}
		End If
	End Function

	Private Sub btnKeyboardGoToProfile_Click(sender As Object, e As EventArgs) Handles btnKeyboardGoToProfile.Click
		If (dgvKeyboard.CurrentCell Is Nothing) OrElse (dgvKeyboard.CurrentCell.RowIndex < 0) Then
			MsgBox("Select keyboard.")
			Exit Sub
		End If
		grpKeyboards.Enabled = False
		grpKeyboardProfiles.Enabled = True
		Me.Refresh()
	End Sub

	Private Sub btnProfileGoToInput_Click(sender As Object, e As EventArgs) Handles btnProfileGoToInput.Click
		If (dgvKeyboardProfile.CurrentCell Is Nothing) OrElse (dgvKeyboardProfile.CurrentCell.RowIndex < 0) Then
			MsgBox("Select profile.")
			Exit Sub
		End If
		grpKeyboardProfiles.Enabled = False
		grpInput.Enabled = True
		Me.Refresh()
	End Sub

	Private Sub btnInputGoToOutput_Click(sender As Object, e As EventArgs) Handles btnInputGoToOutput.Click
		If (dgvInput.CurrentCell Is Nothing) OrElse (dgvInput.CurrentCell.RowIndex < 0) Then
			MsgBox("Select input.")
			Exit Sub
		End If
		grpInput.Enabled = False
		grpOutput.Enabled = True
		Me.Refresh()
	End Sub

	Private Sub btnOutputGoToInput_Click(sender As Object, e As EventArgs) Handles btnOutputGoToInput.Click
		grpOutput.Enabled = False
		grpInput.Enabled = True
		Me.Refresh()
	End Sub

	Private Sub btnInputGoToProfile_Click(sender As Object, e As EventArgs) Handles btnInputGoToProfile.Click
		grpInput.Enabled = False
		grpKeyboardProfiles.Enabled = True
		Me.Refresh()
	End Sub

	Private Sub btnProfileGoToKeyboard_Click(sender As Object, e As EventArgs) Handles btnProfileGoToKeyboard.Click
		grpKeyboardProfiles.Enabled = False
		grpKeyboards.Enabled = True
		Me.Refresh()
	End Sub

	Private Sub btnExitEdit_Click(sender As Object, e As EventArgs) Handles btnExitEdit.Click
		grpKeyboards.Enabled = False
		NewToolStripMenuItem.Enabled = True
		EditToolStripMenuItem.Enabled = True
		LoadToolStripMenuItem.Enabled = True
		SaveToolStripMenuItem.Enabled = True
		SaveAsToolStripMenuItem.Enabled = True
		RunKeyboardSettingsToolStripMenuItem.Enabled = True
		StopToolStripMenuItem.Enabled = False
		Me.Refresh()
	End Sub

	''' <summary>
	''' MENU
	''' </summary>
	Private Sub NewToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles NewToolStripMenuItem.Click
		Form4.ShowDialog()
		If Form4.ExitCode = Form4.ExitCode_Cancel Then
			Return
		End If

		Def.Keyboards.Clear()

		Interception.RightModifierKeysEqualsLeft = Form4.RightModifierKeysEqualsLeft
		Interception.StartKeySequenceWithModifierKeys = Form4.StartKeySequenceWithModifierKeys

		Def.RightModifierKeysEqualsLeft = Form4.RightModifierKeysEqualsLeft
		Def.StartKeySequenceWithModifierKeys = Form4.StartKeySequenceWithModifierKeys

		LoadSave.Filename = Nothing

		dgvKeyboard.Rows.Clear()
		dgvKeyboardProfile.Rows.Clear()
		dgvInput.Rows.Clear()
		dgvOutput.Rows.Clear()

		grpKeyboards.Enabled = True

		NewToolStripMenuItem.Enabled = False
		EditToolStripMenuItem.Enabled = False
		LoadToolStripMenuItem.Enabled = False
		SaveToolStripMenuItem.Enabled = False
		SaveAsToolStripMenuItem.Enabled = False
		RunKeyboardSettingsToolStripMenuItem.Enabled = False
		StopToolStripMenuItem.Enabled = False
		RLModifierKeysEqualityToolStripMenuItem.Checked = Def.RightModifierKeysEqualsLeft
		StartKeySequenceWithModifierKeysToolStripMenuItem.Checked = Def.StartKeySequenceWithModifierKeys
		Me.Text = Title & " - *not named"
		Me.Refresh()
	End Sub

	Private Sub EditToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles EditToolStripMenuItem.Click
		grpKeyboards.Enabled = True

		NewToolStripMenuItem.Enabled = False
		EditToolStripMenuItem.Enabled = False
		LoadToolStripMenuItem.Enabled = False
		SaveToolStripMenuItem.Enabled = False
		SaveAsToolStripMenuItem.Enabled = False
		RunKeyboardSettingsToolStripMenuItem.Enabled = False
		StopToolStripMenuItem.Enabled = False
		Me.Refresh()
	End Sub

	Private Sub SaveToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles SaveToolStripMenuItem.Click
		If LoadSave.Filename Is Nothing Then
			SaveAsToolStripMenuItem_Click(sender, e)
		Else
			LoadSave.UlozTriduDoXML(LoadSave.Filename, Def)
		End If
	End Sub

	Private Sub SaveAsToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles SaveAsToolStripMenuItem.Click
		SaveFileDialog1.InitialDirectory = AppDomain.CurrentDomain.BaseDirectory
		SaveFileDialog1.Filter = "XML files (*.xml)|*.xml"
		If SaveFileDialog1.ShowDialog = System.Windows.Forms.DialogResult.OK Then
			LoadSave.Filename = SaveFileDialog1.FileName
			Me.Text = Title & " - " & Path.GetFileName(LoadSave.Filename)
			LoadSave.UlozTriduDoXML(LoadSave.Filename, Def)
		End If
	End Sub

	Private Sub LoadToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles LoadToolStripMenuItem.Click
		OpenFileDialog1.InitialDirectory = AppDomain.CurrentDomain.BaseDirectory
		OpenFileDialog1.Filter = "XML files (*.xml)|*.xml"
		If OpenFileDialog1.ShowDialog <> System.Windows.Forms.DialogResult.OK Then Return

		LoadKeyboardRemap(OpenFileDialog1.FileName)
	End Sub

	Private Function LoadKeyboardRemap(Filename As String) As Boolean
		If Not File.Exists(Filename) Then
			Return False
		End If

		Dim Def2 As LoadSave.Definice = LoadSave.NactiTriduZXML(Filename, New LoadSave.Definice)
		If Def2 Is Nothing Then
			'LoadSave.Filename = Nothing
			'Me.Text = Title
			MsgBox("Strange format, something bad happened during loading.", MsgBoxStyle.Critical, "Error")
			Return False
		End If

		LoadSave.Filename = Filename
		Def = LoadSave.NactiTriduZXML(LoadSave.Filename, New LoadSave.Definice)
		Me.Text = Title & " - " & Path.GetFileName(LoadSave.Filename)
		LoadSave.AppSettings.PathToLastKeyboardSettings = LoadSave.Filename
		' nacteni dat do DGV
		PridejPolozkyDoDGVkeyboard()

		Interception.RightModifierKeysEqualsLeft = Def.RightModifierKeysEqualsLeft
		Interception.StartKeySequenceWithModifierKeys = Def.StartKeySequenceWithModifierKeys

		RLModifierKeysEqualityToolStripMenuItem.Checked = Def.RightModifierKeysEqualsLeft
		StartKeySequenceWithModifierKeysToolStripMenuItem.Checked = Def.StartKeySequenceWithModifierKeys

		RunKeyboardSettingsToolStripMenuItem.Enabled = True
		StopToolStripMenuItem.Enabled = False

		NewToolStripMenuItem.Enabled = True
		LoadToolStripMenuItem.Enabled = True
		EditToolStripMenuItem.Enabled = True
		SaveToolStripMenuItem.Enabled = True
		SaveAsToolStripMenuItem.Enabled = True

		Return True
	End Function

	Sub PridejPolozkyDoDGVkeyboard()
		RemoveHandler dgvKeyboard.RowEnter, AddressOf dgvKeyboard_RowEnter
		dgvKeyboard.Rows.Clear()
		For Each kb In Def.Keyboards
			dgvKeyboard.Rows.Add()
			dgvKeyboard.Rows(dgvKeyboard.Rows.Count - 1).Cells("cKeyboardName").Value = kb.Name
			dgvKeyboard.Rows(dgvKeyboard.Rows.Count - 1).Cells("cKeyboardHwId").Value = kb.HwID
			dgvKeyboard.Rows(dgvKeyboard.Rows.Count - 1).Cells("cKeyboardEnabled").Value = kb.Enabled
		Next
		' aktivuj prvni radek
		If dgvKeyboard.Rows.Count > 0 Then
			dgvKeyboard.CurrentCell = dgvKeyboard(0, 0)
		End If
		AddHandler dgvKeyboard.RowEnter, AddressOf dgvKeyboard_RowEnter
		' rovnou pridej pro prvni keyboard jeho profily
		PridejPolozkyDoDGVkeyboardProfile(0)
	End Sub

	Sub PridejPolozkyDoDGVkeyboardProfile(KeyboardIndex As Integer)
		Try
			Dim hlp As LoadSave.Keyboard = Def.Keyboards(KeyboardIndex)
		Catch ex As Exception
			dgvKeyboardProfile.Rows.Clear()
			dgvInput.Rows.Clear()
			dgvOutput.Rows.Clear()
			Return
		End Try
		RemoveHandler dgvKeyboardProfile.RowEnter, AddressOf dgvKeyboardProfile_RowEnter
		RemoveHandler dgvKeyboardProfile.RowsAdded, AddressOf dgvKeyboardProfile_RowsAdded
		dgvKeyboardProfile.Rows.Clear()
		For Each p In Def.Keyboards(KeyboardIndex).Profiles
			dgvKeyboardProfile.Rows.Add()
			dgvKeyboardProfile.Rows(dgvKeyboardProfile.Rows.Count - 1).Cells("cProfileName").Value = p.Name
			dgvKeyboardProfile.Rows(dgvKeyboardProfile.Rows.Count - 1).Cells("cProfileEnabled").Value = p.Enabled
		Next
		' aktivuj prvni radek
		If dgvKeyboardProfile.Rows.Count > 0 Then
			dgvKeyboardProfile.CurrentCell = dgvKeyboardProfile(0, 0)
		End If
		AddHandler dgvKeyboardProfile.RowEnter, AddressOf dgvKeyboardProfile_RowEnter
		AddHandler dgvKeyboardProfile.RowsAdded, AddressOf dgvKeyboardProfile_RowsAdded
		' pridej pro vybranej keyboard a pro prvni profil dany inputy
		PridejPolozkyDoDGVinput(KeyboardIndex, 0)
	End Sub

	Sub PridejPolozkyDoDGVinput(KeyboardIndex As Integer, ProfileIndex As Integer)
		Try
			Dim hlp As LoadSave.Profile = Def.Keyboards(KeyboardIndex).Profiles(ProfileIndex)
		Catch ex As Exception
			dgvInput.Rows.Clear()
			dgvOutput.Rows.Clear()
			Return
		End Try
		RemoveHandler dgvInput.RowEnter, AddressOf dgvInput_RowEnter
		RemoveHandler dgvInput.RowsAdded, AddressOf dgvInput_RowsAdded
		dgvInput.Rows.Clear()
		For Each i In Def.Keyboards(KeyboardIndex).Profiles(ProfileIndex).Inputs
			dgvInput.Rows.Add()
			dgvInput.Rows(dgvInput.Rows.Count - 1).Cells("cInputName").Value = i.Name
			If (i.Strokes Is Nothing) OrElse (i.Strokes.Count = 0) Then
				dgvInput.Rows(dgvInput.Rows.Count - 1).Cells("cInputKeyCombination").Value = "- click to set -"
			Else
				dgvInput.Rows(dgvInput.Rows.Count - 1).Cells("cInputKeyCombination").Value = DejRetezecZeSeznamuStroku(i.Strokes)

			End If
			dgvInput.Rows(dgvInput.Rows.Count - 1).Cells("cInputEnabled").Value = i.Enabled
		Next
		' aktivuj prvni radek
		If dgvInput.Rows.Count > 0 Then
			dgvInput.CurrentCell = dgvInput(0, 0)
		End If
		AddHandler dgvInput.RowEnter, AddressOf dgvInput_RowEnter
		AddHandler dgvInput.RowsAdded, AddressOf dgvInput_RowsAdded
		' pridej pro vybrany keyboard a profil a prvni input dany outputy
		PridejPolozkyDoDGVoutput(KeyboardIndex, ProfileIndex, 0)
	End Sub

	Sub PridejPolozkyDoDGVoutput(KeyboardIndex As Integer, ProfileIndex As Integer, InputIndex As Integer)
		Try
			Dim hlp As LoadSave.Input = Def.Keyboards(KeyboardIndex).Profiles(ProfileIndex).Inputs(InputIndex)
		Catch ex As Exception
			dgvOutput.Rows.Clear()
			Return
		End Try
		RemoveHandler dgvOutput.RowEnter, AddressOf dgvOutput_RowEnter
		dgvOutput.Rows.Clear()
		For Each o In Def.Keyboards(KeyboardIndex).Profiles(ProfileIndex).Inputs(InputIndex).Outputs
			dgvOutput.Rows.Add()
			If (o.Strokes Is Nothing) OrElse (o.Strokes.Count = 0) Then
				dgvInput.Rows(dgvInput.Rows.Count - 1).Cells("cInputKeyCombination").Value = "- click to set -"
			Else
				dgvOutput.Rows(dgvOutput.Rows.Count - 1).Cells("cOutputKeyCombination").Value = DejRetezecZeSeznamuStroku(o.Strokes)
			End If
			dgvOutput.Rows(dgvOutput.Rows.Count - 1).Cells("cOutputEnabled").Value = o.Enabled
		Next
		' aktivuj prvni radek
		If dgvOutput.Rows.Count > 0 Then
			dgvOutput.CurrentCell = dgvOutput(0, 0)
		End If
		AddHandler dgvOutput.RowEnter, AddressOf dgvOutput_RowEnter
	End Sub

	Private Sub RLModifierKeysEqualityToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles RLModifierKeysEqualityToolStripMenuItem.Click
		RLModifierKeysEqualityToolStripMenuItem.Checked = Not RLModifierKeysEqualityToolStripMenuItem.Checked
		Interception.RightModifierKeysEqualsLeft = RLModifierKeysEqualityToolStripMenuItem.Checked
	End Sub

	Private Sub StartKeySequenceWithModifierKeysToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles StartKeySequenceWithModifierKeysToolStripMenuItem.Click
		StartKeySequenceWithModifierKeysToolStripMenuItem.Checked = Not StartKeySequenceWithModifierKeysToolStripMenuItem.Checked
		Interception.StartKeySequenceWithModifierKeys = StartKeySequenceWithModifierKeysToolStripMenuItem.Checked
	End Sub

	Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged

	End Sub

	Private Sub Form1_Resize(sender As Object, e As EventArgs) Handles MyBase.Resize
		If Me.WindowState = FormWindowState.Minimized Then
			Me.Hide()
		End If
	End Sub

	Private Sub NotifyIcon1_Click(sender As Object, e As EventArgs) Handles NotifyIcon1.Click
		Me.Show()
		Me.WindowState = FormWindowState.Normal
		Me.Activate()
		Me.Focus()
	End Sub

	Private Sub Form1_FormClosed(sender As Object, e As FormClosedEventArgs) Handles MyBase.FormClosed
		btnStop_Click(sender, e)
		RegisterInStartup(RunTheseKeyboardSettingsOnWindowsStartToolStripMenuItem.Checked)
		LoadSave.UlozNastaveni()
	End Sub

	Private Sub LoggingToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles LoggingToolStripMenuItem.Click
		LoggingToolStripMenuItem.Checked = Not LoggingToolStripMenuItem.Checked
		Interception.Logging = LoggingToolStripMenuItem.Checked
		NastavSirkuFormulare(Interception.Logging)
	End Sub

	Private Sub NastavSirkuFormulare(b As Boolean)
		If b Then
			Me.Width = lstProgress.Location.X + lstProgress.Size.Width + lstProgress.Margin.Left + lstProgress.Margin.Right + 20
		Else
			Me.Width = grpOutput.Location.X + grpOutput.Size.Width + grpOutput.Margin.Left + grpOutput.Margin.Right + 40
		End If
	End Sub


	Private Sub RegisterInStartup(isChecked As Boolean)
		Dim registryKey As RegistryKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Run", True)

		If isChecked Then
			registryKey.SetValue(Application.ProductName, Application.ExecutablePath & " -StartFromRegistry")
			AppSettings.AutoStart = True
		Else
			Try
				registryKey.DeleteValue(Application.ProductName)
			Catch ex As Exception
			End Try
			AppSettings.AutoStart = False
		End If
	End Sub

	Private Sub RunTheseKeyboardSettingsOnWindowsStartToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles RunTheseKeyboardSettingsOnWindowsStartToolStripMenuItem.Click
		RunTheseKeyboardSettingsOnWindowsStartToolStripMenuItem.Checked = Not RunTheseKeyboardSettingsOnWindowsStartToolStripMenuItem.Checked
	End Sub

	Private Sub ExitToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ExitToolStripMenuItem.Click
		Me.Close()
	End Sub

	Private Sub AboutToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles AboutToolStripMenuItem.Click
		Form5.ShowDialog()
	End Sub

	Private Sub HelpToolStripMenuItem1_Click(sender As Object, e As EventArgs) Handles HelpToolStripMenuItem1.Click
		Process.Start(AppDomain.CurrentDomain.BaseDirectory & "Help.pdf")
	End Sub
End Class
